# -*- coding: utf-8 -*-
# 作者： 安智军
# @Time：2022/7/10 9:31
# @Email：1010666711@qq.com
# @File： 好用的内置函数.py
'''
#1、filter(怎么过滤，要过滤的对象)过滤 从可迭代的对象中筛选出满足条件的元素
# 2 、map （如何映射，【要映射的对象1，要映射的对象1，。。。。。】） 映射

# 3、reduce 入参的第一个数是函数的返回结果和下一个数相加  和累加不一样

# 4、 zip 把两个列表压成一个元组
'''

from functools import reduce

'''
    """
    reduce(function, sequence[, initial]) -> value
    
    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.
    """

'''
# 一、filter
print(help(filter))

'''
class filter(object)
 |  filter(function or None, iterable) --> filter object
 |  
 |  Return an iterator yielding those items of iterable for which function(item)
 |  is true. If function is None, return the items that are true.

'''


def filter_test():
    def f(x):
        if x > 2:
            return True  # 为True 时不对 [1,2,3,4] 中的所有元素依次进行f操
            # return None  # 为None 时不对 [1,2,3,4] 中的所有元素依次进行f操作
        return False

    # 方法一
    return filter(f,[1,2,3,4])  # 对 [1,2,3,4] 中的所有元素依次进行f操作
    # return filter(f,[1,2,3,4])  # 对 [1,2,3,4] 中的所有元素依次进行f操作
    # 方法二 最优雅的方法使用filter 使用lambda
    # return filter(lambda x: x > 2, [1, 2, 3, 4])  # 对 [1,2,3,4] 中的所有元素依次进行f操作

    # return filter(None,[1,2,3,4])


if __name__ == '__main__':
    for value in filter_test():
        print(value)
'''
None
1
2
3
4

'''


# map 函数

def map_test():
    '''
    map 对象是个迭代器 所以可以用for循环
     |  map(func, *iterables) --> map object
 |
 |  Make an iterator that computes the function using arguments from
 |  each of the iterables.  Stops when the shortest iterable is exhausted.
    :return:
    '''
    # return map(lambda x:(2*x+2),[1,2,3]) # map不是函数 是对象  map(func, *iterables) --> map object
    # 把两个列表中 每个元素相加生成新的列表 两个列表的个数相同 【1,2,3,4】 【5,6,7,8】---》【6,8,10,12】
    # 方法一、不使用 map实现两个列表相加值为新列表
    nums1 = [1, 2, 3, 4]
    nums2 = [5, 6, 7, 8]
    new_num = []
    # 使用for循环实现
    for i, vale in enumerate(nums1):
        new_num.append(value + nums2[i])

    # 方法二、使用map进行相加 运行效率是map的效率高
    nums3 = [1, 2, 3, 4]
    nums4 = [5, 6, 7, 8]
    nums5 = [9, 10, 11, 12]
    print(list(map(lambda i, j, g: i + j + g, nums3, nums4, nums5)))  # 使用map实现 两个列表的相加值为一个新列表 [9, 10, 11, 12]

    # 方法三 不用lambda 只使用 map 等价于 方法二 使用匿名函数是最优雅的 比额外定义一个函数更好
    def f(x, y, z):
        return x + y + z

    print('f函数：', list(map(f, nums3, nums4, nums5)))  # 使用map实现 两个列表的相加值为一个新列表 [9, 10, 11, 12]

    # print(list(map(lambda i, j,g: i + j+g, nums3, nums4,nums5)))  # 使用map实现 两个列表的相加值为一个新列表 [9, 10, 11, 12]

    print(new_num)
    # return  map()
    return new_num


if __name__ == '__main__':
    # print(help(map))
    print(map_test())  # 返回map对象  <map object at 0x00000241F8BDDA48>
    # 对象取值 去循环
    # for value in map_test():
    #     print(value)

'''
<map object at 0x000001C57F45DAC8>
4
6
8


'''


# reduce

# 累加功能

def reduce_test():
    '''
    累加功能 1-5做累加

    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).
    :return:
    '''

    def f(x,y): # 把函数返回值当做第一个参数  和第二个值相加 和累加不一样
        result = x+y
        return result

    reduce(f,[1,2,3,4,5])
    print(sum([3,6,9]))


if __name__ == '__main__':
    reduce_test()


# 不使用 reduce 方法 使用最普通的方法实现累加
def f():
    sum = 0
    for i in [1, 2, 3, 4, 5]:
        sum += i
    return sum



if __name__ == '__main__':
    common = reduce_test()
    print(f())



def zip_test():
    '''
    zip(iter1 [,iter2 [...]]) --> zip object

    举例：zip('zxcv',range(4),range(4))----> [(z,0,0), (x,1,1),(c,2,2)]
    :return:
    '''
    help(zip)
    print(list(zip('zxcv', range(4), range(4))))  # [('z', 0, 0), ('x', 1, 1), ('c', 2, 2), ('v', 3, 3)]

if __name__ == '__main__':
    zip_test()



# print(dir(__builtins__))

import builtins    # Python2 无 module builtins

print(dir(builtins))
print(dir(list))